<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\ContactBatchAdd\Listener;

use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Utils\Codec\Json;
use MoChat\App\Corp\Contract\CorpContract;
use MoChat\App\Corp\Utils\WeWorkFactory;
use MoChat\App\WorkContact\Contract\WorkContactContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkContact\Event\AddContactEvent;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\Plugin\AutoTag\Action\Dashboard\Traits\AutoContactTag;
use MoChat\Plugin\ContactBatchAdd\Contract\ContactBatchAddImportContract;
use MoChat\Plugin\ContactBatchAdd\Contract\ContactBatchAddImportRecordContract;
use Psr\Container\ContainerInterface;

/**
 * 添加企业客户事件.
 *
 * @Listener(priority=9999)
 */
class ContactBatchAddListener implements ListenerInterface
{
    use AutoContactTag;

    /**
     * @Inject
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var WorkContactContract
     */
    protected $workContactService;

    /**
     * @Inject
     * @var CorpContract
     */
    protected $corpService;

    /**
     * @Inject
     * @var WeWorkFactory
     */
    protected $weWorkFactory;

    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployeeService;

    /**
     * @Inject
     * @var ContactBatchAddImportContract
     */
    protected $contactBatchAddImportService;

    /**
     * @Inject
     * @var ContactBatchAddImportRecordContract
     */
    protected $contactBatchAddImportRecordService;

    /**
     * @Inject
     * @var WorkContactEmployeeContract
     */
    protected $workContactEmployeeService;

    public function listen(): array
    {
        return [
            AddContactEvent::class,
        ];
    }

    public function process(object $event): array
    {
        try {
            $contact = $event->message;
            $this->logger = $this->container->get(StdoutLoggerInterface::class);
            $this->workContactService = $this->container->get(WorkContactContract::class);

            $this->logger->info('触发批量添加好友回调了：' . json_encode($event->message, JSON_THROW_ON_ERROR));

            // 校验 - 微信回调参数
            if (empty($contact) || empty($contact['id']) || empty($contact['employeeId']) || empty($contact['wxExternalUserid'])) {
                $this->logger->info('批量添加好友回调：回调信息错误');
                return [];
            }

            $corpId = (int) $contact['corpId'];
            $contactId = (int) $contact['id'];
            $employeeId = (int) $contact['employeeId'];
            $wxExternalUserid = $contact['wxExternalUserid'];

            // 员工
            $employee = $this->workEmployeeService->getWorkEmployeeById($employeeId, ['id', 'name', 'wx_user_id']);
            if (empty($employee)) {
                $this->logger->info('批量添加好友回调：未查到员工信息' . $contact['employeeId']);
                return [];
            }
            $employeeWxUserId = $employee['wxUserId'];
            $contactWxExternalUserId = $wxExternalUserid;
            $wxContactRes = $this->weWorkFactory->getContactApp($corpId)->external_contact->get($contactWxExternalUserId);
            if ($wxContactRes['errcode'] !== 0) {
                $this->logger->error(sprintf('%s [%s] 请求数据：%s 响应结果：%s', '获取外部联系人详情错误', date('Y-m-d H:i:s'), $contactWxExternalUserId, Json::encode($wxContactRes)));
                return [];
            }
            $followEmployee = $this->getFollowEmployee($wxContactRes['follow_user'], $employeeWxUserId);

            if ($followEmployee['add_way'] !== 2) {
                $this->logger->info('批量添加好友回调：不是通过手机号添加的，add_way:' . $followEmployee['add_way']);
                return [];
            }

            // 备注手机号
            $remarkMobiles = $followEmployee['remark_mobiles'] ?? '';
            if (empty($remarkMobiles)) {
                $this->logger->info('批量添加好友回调：没有备注手机号信息' . Json::encode($remarkMobiles));
                return [];
            }
            // 批量添加好友回调好逻辑处理
            $this->contactBatchAdd($corpId, (array) $remarkMobiles, $employee, $contact);
        } catch (\Throwable $e) {
            $this->logger->error(sprintf('[批量加好友]客户添加处理失败，错误信息: %s', $e->getMessage()));
            $this->logger->error($e->getTraceAsString());
        }

        return [];
    }

    /**
     * @return array|mixed
     */
    private function getFollowEmployee(array $followUser, string $employeeWxUserId)
    {
        $followEmployee = [];
        foreach ($followUser as $follow) {
            if ($follow['userid'] == $employeeWxUserId) {
                $followEmployee = $follow;
            }
        }
        return $followEmployee;
    }

    private function contactBatchAdd($corpId, $remarkMobiles, $employee, $contact)
    {
        if (empty($remarkMobiles)) {
            return;
        }

        foreach ($remarkMobiles as $phone) {
            if (empty($phone) || ! is_string($phone)) {
                continue;
            }

            // 查询导入记录
            $import = $this->contactBatchAddImportService->getContactBatchAddImportByCorpIdPhoneEmployeeIdStatus($corpId, (string) $phone, $employee['id'], 2, ['id', 'record_id', 'remark', 'tags']);
            if (empty($import)) {
                $this->logger->info('批量添加好友回调：没有查到导入信息' . $corpId . '-' . $phone . '-' . $employee['id']);
                continue;
            }

            // 修改添加状态为已添加
            $this->contactBatchAddImportService->updateContactBatchAddImportById($import['id'], ['status' => 3]);
            // 已添加客户数+1
            $record = $this->contactBatchAddImportRecordService->getContactBatchAddImportRecordById($import['recordId'], ['tags', 'add_num']);
            $this->contactBatchAddImportRecordService->updateContactBatchAddImportRecordById($import['recordId'], ['add_num' => $record['addNum'] + 1]);
            // 打标签
            if (! empty($record['tags'])) {
                $tagIds = (array) $record['tags'];
                if (! empty($tagIds)) {
                    $data['tagArr'] = $tagIds;
                    // 客户
                    $data['contactId'] = $contact['id'];
                    $data['contactWxExternalUserid'] = $contact['wxExternalUserid'];
                    // 员工
                    $data['employeeId'] = $contact['employeeId'];
                    $data['employeeWxUserId'] = $employee['wxUserId'];
                    $this->autoTag($data);
                }
            }
            // 处理备注
            if (! empty($import['remark'])) {
                $this->workContactEmployeeService->updateWorkContactEmployeeByOtherIds($contact['employeeId'], $contact['id'], ['remark' => $import['remark']]);
            }
        }
    }
}
